﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

public class WordBookmarkReplacer
{
    /// <summary>
    /// Word模板生成入口：替换书签、占位符、表格
    /// </summary>
    public static void GenerateWord(string templatePath, string outputPath, BookData bookData)
    {
        if (!File.Exists(templatePath))
            throw new FileNotFoundException("模板文件不存在: " + templatePath);

        // 复制模板到输出文件（保留原模板）
        File.Copy(templatePath, outputPath, true);

        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(outputPath, true))
        {
            // 替换书签
            if (bookData.marks?.Count > 0)
                ReplaceBookmarks(wordDoc, bookData.marks);

            // 替换占位符
            if (bookData.placeholders?.Count > 0)
                ReplacePlaceholders(wordDoc, bookData.placeholders);

            // 插入表格数据
            if (bookData.tables?.Count > 0)
            {
                foreach (var kv in bookData.tables)
                {
                    InsertRowsToTable(wordDoc, kv.Key, kv.Value);
                }
            }

            wordDoc.MainDocumentPart.Document.Save();
        }
    }

    #region === 书签替换 ===
    public static void ReplaceBookmarks(WordprocessingDocument wordDoc, Dictionary<string, string> replacements)
    {
        var mainPart = wordDoc.MainDocumentPart;
        if (mainPart?.Document?.Body == null)
            throw new Exception("Word 文档不包含有效内容。");

        var bookmarks = mainPart.Document.Body.Descendants<BookmarkStart>();

        foreach (var bookmark in bookmarks)
        {
            string bookmarkName = bookmark.Name;
            if (!replacements.ContainsKey(bookmarkName))
                continue;

            string newText = replacements[bookmarkName] ?? string.Empty;
            var parent = bookmark.Parent;

            // 删除 BookmarkStart 与 BookmarkEnd 之间的内容
            var nextElement = bookmark.NextSibling();
            while (nextElement != null && !(nextElement is BookmarkEnd be && be.Id == bookmark.Id))
            {
                var toRemove = nextElement;
                nextElement = nextElement.NextSibling();
                toRemove.Remove();
            }

            // 插入新文本
            Run run = new Run(new Text(newText));
            parent.InsertAfter(run, bookmark);
        }
    }
    #endregion

    #region === 占位符替换 ===
    public static void ReplacePlaceholders(WordprocessingDocument doc, Dictionary<string, string> replacements)
    {
        var body = doc.MainDocumentPart.Document.Body;
        var texts = body.Descendants<Text>().ToList();

        foreach (var text in texts)
        {
            if (string.IsNullOrEmpty(text.Text)) continue;

            foreach (var kv in replacements)
            {
                string placeholder = kv.Key;
                string newValue = kv.Value ?? string.Empty;

                if (text.Text.Contains(placeholder))
                {
                    text.Text = text.Text.Replace(placeholder, newValue);
                }
            }
        }
    }
    #endregion


    #region === 表格插入 ===

    /// <summary>
    /// 向指定索引的表格插入多行数据（基于模板行克隆），内容显示正常且不会多余换行
    /// </summary>
    /// <param name="doc">打开的 Word 文档对象</param>
    /// <param name="tableIndex">表格索引（0-based）</param>
    /// <param name="data">要插入的行数据，每个 List&lt;string&gt; 表示一行</param>
    public static void InsertRowsToTable(WordprocessingDocument doc, int tableIndex, List<List<string>> data)
    {
        var body = doc.MainDocumentPart.Document.Body;
        var tables = body.Elements<Table>().ToList();

        if (tableIndex < 0 || tableIndex >= tables.Count)
            throw new IndexOutOfRangeException($"表格索引 {tableIndex} 不存在（当前文档只有 {tables.Count} 个表格）。");

        var table = tables[tableIndex];
        var allRows = table.Elements<TableRow>().ToList();
        if (allRows.Count == 0)
            throw new Exception("目标表格没有任何行，无法复制模板行。");

        // 使用最后一行为模板行
        var templateRow = allRows.Last();

        foreach (var rowData in data)
        {
            var newRow = (TableRow)templateRow.CloneNode(true);
            var cells = newRow.Elements<TableCell>().ToList();

            for (int i = 0; i < cells.Count && i < rowData.Count; i++)
            {
                var cell = cells[i];

                // 清空单元格内容
                cell.RemoveAllChildren<Paragraph>();

                // 创建新的 Paragraph + Run + Text 插入数据
                var para = new Paragraph(new Run(new Text(rowData[i])));
                cell.Append(para);
            }

            // 插入到表格末尾
            table.InsertAfter(newRow, allRows.Last());
            allRows.Add(newRow);
        }
    }

    #endregion



    #region === 数据结构 ===
    public class BookData
    {
        /// <summary>书签替换内容</summary>
        public Dictionary<string, string> marks { get; set; } = new Dictionary<string, string>();

        /// <summary>占位符替换内容</summary>
        public Dictionary<string, string> placeholders { get; set; } = new Dictionary<string, string>();

        /// <summary>表格插入数据（Key=表格索引，Value=要插入的数据行）</summary>
        public Dictionary<int, List<List<string>>> tables { get; set; } = new Dictionary<int, List<List<string>>>();
    }
    #endregion
}
